iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
JavaScript

大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript系列 第 6

【Day 6】Java 規定只能有一個老爸怎麼辦?用 Interface 外掛你的第二個身分!

  • 分享至 

  • xImage
  •  

昨天我們聊到繼承的鐵則:一個 Class 只能有一個老爸(單一繼承)。老爸寫好的程式碼,小孩可以直接拿來用。
但現實開發中,常常會遇到兩種讓人頭痛的情境:

  • 老爸自己也不知道細節該怎麼寫:例如「動物(Animal)」都會移動或發出叫聲,但魚用游的、鳥用飛的、狗叫聲是汪汪、豬叫聲是哼哼。父類別根本不可能寫出一套全體適用的叫聲。
  • 需要身兼多職學技能:一隻豬(Pig)在動物學上是「動物」,但在廚師眼裡牠是「可食用的食材(Edible)」。既然 Java 不允許認兩個老爸,該怎麼賦予牠第二個身分?
    為了解決這兩種窘境,Java 派出了兩位救援神隊友:
    畫餅專家「抽象類別(Abstract Class)」:老爸負責出考卷立項,把共通的先寫好,寫不出來的留白,讓小孩自己交出專屬答案。
    外掛技能包「介面(Interface)」:既然不能認第二個老爸,那就用「簽技能合約」的方式,想兼幾份差、拿幾張證照,通通隨你簽!

抽象類別(Abstract Class):寫了一半的半成品試卷
在類別前面掛上 abstract,它就正式變成抽象類別。它的靈魂在於:共通的答案老爸先幫你寫好,專屬的申論題留白讓你自由發揮。
Java
public abstract class Animal {
// 1. 選擇題(一般方法):大家呼吸都一樣,老爸直接寫好完整大括號 {}
public void breathe() {
System.out.println("呼吸空氣中...");
}

// 2. 申論題(抽象方法):老爸只出題目立項,後面沒有大括號 {},只有一個分號 ; 結尾
public abstract void makeSound();

}
為什麼抽象類別絕對不能 new?
如果有人想不開寫出 Animal a = new Animal();,編譯器會當場亮紅字阻擋,原因非常簡單:
世上根本沒有一種生物叫「動物」:
現實中你能看到貓、摸到狗,但抓不出一個純粹的動物實體。概念無法直接具象化,它只是個大分類。
空頭支票發不出聲音:
老爸的 makeSound() 後面連個大括號 {} 都沒有,資訊根本不齊全。如果 Java 准許你生出這個物件,當你呼叫它時,電腦根本不知道該播放狗吠還是貓叫,不可能對著空氣猜你的心意。
繼承抽象類別:拿老爸的考卷交出自己的答案
當子類別繼承抽象老爸時,就像在考場領到這份「寫了一半的考卷」:
坐享其成(是非選擇題):
呼吸方式大家完全相同,貓咪直接承襲老爸寫好的 breathe(),連一行程式碼都不必重打。
各憑本事(申論題):
考卷上訂了題目:「請作答你該怎麼叫?」後面的空白處老爸不幫你填,必須用@Override覆寫填上自己的大括號。身為貓咪,你的申論題就填「喵喵喵」;身為小狗,你的申論題就填「汪汪汪」。
每個人依自己的身分交出專屬答案,把整張考卷的空格全部填滿,這張圖紙才算正式完工,也才能真正產生實體!

public class Cat extends Animal {
// 把老爸留白的申論題填滿!
@Override
public void makeSound() {
System.out.println("喵喵喵!");
}
}
把老爸未完工的申論題全數作答完畢,這張藍圖才算真正合格落成,這時你才能放心大喊 new Cat(),把活生生的貓咪實體召喚出來!
2. 介面(Interface):「外掛技能合約包」
在 Java 的世界裡,家規非常嚴格:一個 Class 只能認一個老爸(單一繼承)。
小豬(Pig)已經繼承了動物老爸(Animal),但今天米其林大廚走過來,想賦予小豬第二個身分「可食用食材」,這時小豬不能再去認廚房當乾爹,該怎麼辦?
答案就是:祭出 interface(介面)簽合約!
介面是個甩手掌櫃,它一丁點程式碼都不寫,純粹開出一張「空頭規格清單」:

public interface Edible {
// 介面裡只開規格:誰簽約,誰就必須交代「到底怎麼吃」!
String youMayEat();
}
implements 就是:身分認證簽約,加分題自己答!
小豬想兼差獲得「食材證照」,就在類別後面大方寫上 implements Edible(簽署實作合約):

// 小豬只有一個親生老爸 Animal,但簽下 Edible 食材技能合約!
public class Pig extends Animal implements Edible {

// 1. 履行老爸 Animal 的基本義務(把申論題填完)
@Override
public void makeSound() {
    System.out.println("Oink! ");
}

// 2. 履行 Edible 合約的技能承諾(加分題交代如何食用)
@Override
public String youMayEat() {
    return "可以做成美味的炸豬排!";
}

}
為什麼介面能讓小豬「身兼多職、海納百川」?
血緣只有一個,身分可以無限多:
小豬只能有一個老爸(extends Animal),但它可以同時簽好幾份合約:
implements Edible, Pet, Sellable
它既是「可食用的(Edible)」、又是「寵物(Pet)」、還是「可買賣的商品(Sellable)」。
你只要敢簽名(implements),就必須在自己的大括號裡,把(抽象方法)一題一題用 @Override 交代清楚,程式才算合格過關!
一句話記住:
extends 決定你是誰的種,implements 決定你身上掛了幾張專業證照!


上一篇
【Day 5】繼承不是複製貼上!看 Teacher 如何共享 Person 的規格並擴充 subjectName
下一篇
【Day 7】左邊掛統一識別證,右邊各自精采,一個迴圈搞定全場的多型魔法
系列文
大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言